const fs = require('fs');
const http = require('http');
const template = require('art-template');
template.defaults.root = __dirname + '/template';

const args = process.argv.slice(2);

// let root = process.cwd();
let root = '.';

function readArg() {
    if (args[0]) {
        root = args[0];
    }
    console.log('服务器的 Root 路径为: ' + root);
}
readArg();

// 启动服务
function initServer() {
    let server = http.createServer();
    server.on('request', processHttp);
    server.listen(80, function () {
        console.log('启动成功');
    });
}
initServer();

// 处理 HTTP 请求
function processHttp(req, resp) {
    // 根据 req 传入的 url 决定访问的文件路径   
    let fileName = root + req.url;
    // 判定文件存在
    if (!fs.existsSync(fileName)) {
        resp.statusCode = 404;
        resp.end('<h1>页面未找到!</h1>');
        return;
    }
    // 判定文件类型, 针对目录和普通文件分别处理. 
    let stat = fs.statSync(fileName);
    if (stat.isDirectory()) {
        // 处理目录的情况
        processDir(fileName, resp);
    } else {
        // 处理文件的情况
        processFile(fileName, resp);
    }
}

function processDir(dirName, resp) {
    // 1. 列出目录中的内容
    let files = fs.readdirSync(dirName);
    let results = [];
    files.forEach(function (fileName) {
        if (dirName.charAt(dirName.length - 1) != '/') {
            dirName += '/';
        }
        let pathName = dirName + fileName;
        let stat = fs.statSync(pathName);
        results.push({
            fileName: fileName,
            pathName: pathName,
            isDir: stat.isDirectory(),
        });
    });
    // 2. 渲染模板
    let html = template('template.html', {
        title: dirName,
        results: results
    });
    resp.end(html);
}

function processFile(fileName, resp) {
    // 1. 根据文件扩展名, 决定 content-type
    let ext = getExt(fileName);
    let extMap = buildExtMap();
    let contentType = extMap.get(ext);
    // console.log('fileName: ', fileName)
    // console.log('ext: ', ext);
    // console.log('contentType: ', contentType);
    // console.log('=============================');

    if (contentType) {
        resp.setHeader('Content-Type', contentType);
    }
    // 2. 读取文件内容
    if (contentType && contentType.indexOf('image') >= 0) {
        // 如果是图片, 则读文件的时候不能指定 utf8
        fs.readFile(fileName, function (err, data) {
            resp.end(data);
        });
    } else {
        // 如果是文本文件, 则可以指定 utf-8
        fs.readFile(fileName, 'utf-8', function (err, data) {
            resp.end(data);
        });
    }
}

function getExt(fileName) {
    let pos = fileName.lastIndexOf('.');
    if (pos == -1) {
        return '';
    }
    return fileName.substring(pos).toLowerCase();
}

function buildExtMap() {
    let extMap = new Map();
    extMap.set('.html', 'text/html; charset=utf-8');
    extMap.set('.css', 'text/css; charset=utf-8');
    extMap.set('.js', 'application/javascript; charset=utf-8');
    extMap.set('.json', 'application/json; charset=utf-8');
    extMap.set('.jpg', 'image/jpg');
    extMap.set('.png', 'image/png');
    extMap.set('.jpeg', 'image/jpeg');
    return extMap;
}
